package com.liuhuanss.voiceprint.controller;

import com.liuhuanss.voiceprint.dto.ApiResponse;
import com.liuhuanss.voiceprint.dto.LoginRequest;
import com.liuhuanss.voiceprint.dto.RegisterRequest;
import com.liuhuanss.voiceprint.dto.VoiceprintLoginRequest;
import com.liuhuanss.voiceprint.entity.User;
import com.liuhuanss.voiceprint.service.UserService;
import com.liuhuanss.voiceprint.service.AuthService;
import com.liuhuanss.voiceprint.service.VoiceprintService;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 * 
 * @author liuhuanss
 * @version 1.0
 */
@RestController
@RequestMapping("/api/auth")
@CrossOrigin(origins = "*")
@Slf4j
public class AuthController {

    @Autowired
    private UserService userService;
    
    @Autowired
    private AuthService authService;
    
    @Autowired
    private VoiceprintService voiceprintService;

    /**
     * 用户注册
     * 
     * @param registerRequest 注册请求
     * @return 注册结果
     */
    @PostMapping("/register")
    public ResponseEntity<ApiResponse<Map<String, Object>>> register(@Valid @RequestBody RegisterRequest registerRequest) {
        try {
            log.info("收到用户注册请求: {}", registerRequest);
            
            User user = userService.registerUser(registerRequest);
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", user.getId());
            responseData.put("username", user.getUsername());
            responseData.put("email", user.getEmail());
            responseData.put("voiceprintEnabled", user.getIsVoiceprintEnabled());
            responseData.put("createdAt", user.getCreatedAt());
            
            return ResponseEntity.ok(ApiResponse.success("注册成功", responseData));
        } catch (Exception e) {
            log.error("用户注册失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "REGISTER_FAILED"));
        }
    }

    /**
     * 用户登录
     * 
     * @param loginRequest 登录请求
     * @return 登录结果
     */
    @PostMapping("/login")
    public ResponseEntity<ApiResponse<Map<String, Object>>> login(@Valid @RequestBody LoginRequest loginRequest) {
        try {
            log.info("收到用户登录请求: {}", loginRequest);
            
            User user = userService.loginUser(loginRequest);
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", user.getId());
            responseData.put("username", user.getUsername());
            responseData.put("email", user.getEmail());
            responseData.put("voiceprintEnabled", user.getIsVoiceprintEnabled());
            responseData.put("loginType", loginRequest.getLoginType());
            responseData.put("loginTime", java.time.LocalDateTime.now());
            
            // 这里可以生成JWT token
            responseData.put("token", generateToken(user));
            
            return ResponseEntity.ok(ApiResponse.success("登录成功", responseData));
        } catch (Exception e) {
            log.error("用户登录失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "LOGIN_FAILED"));
        }
    }

    /**
     * 声纹登录（文件上传）
     * 
     * @param username 用户名
     * @param audioFile 音频文件
     * @return 登录结果
     */
    @PostMapping("/voiceprint-login")
    public ResponseEntity<ApiResponse<Map<String, Object>>> voiceprintLogin(
            @RequestParam("username") String username,
            @RequestParam("audioFile") MultipartFile audioFile) {
        try {
            log.info("收到声纹登录请求，用户名: {}, 文件: {}", 
                    username, audioFile.getOriginalFilename());
            
            // 参数验证
            if (username == null || username.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("用户名不能为空", "INVALID_USERNAME")
                );
            }
            
            if (audioFile == null || audioFile.isEmpty()) {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("音频文件不能为空", "INVALID_AUDIO_FILE")
                );
            }
            
            Map<String, Object> result = authService.voiceprintLogin(username.trim(), audioFile);
            
            return ResponseEntity.ok(ApiResponse.success("声纹登录成功", result));
        } catch (Exception e) {
            log.error("声纹登录失败", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "VOICEPRINT_LOGIN_FAILED")
            );
        }
    }

    /**
     * 声纹登录（Base64数据）
     * 
     * @param request 声纹登录请求
     * @return 登录结果
     */
    @PostMapping("/voiceprint-login-base64")
    public ResponseEntity<ApiResponse<Map<String, Object>>> voiceprintLoginBase64(
            @Valid @RequestBody VoiceprintLoginRequest request) {
        try {
            log.info("收到声纹登录请求（Base64），用户名: {}", request.getUsername());
            
            Map<String, Object> result = authService.voiceprintLogin(
                request.getUsername(), 
                request.getAudioBase64()
            );
            
            return ResponseEntity.ok(ApiResponse.success("声纹登录成功", result));
        } catch (Exception e) {
            log.error("声纹登录失败（Base64）", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "VOICEPRINT_LOGIN_FAILED")
            );
        }
    }

    /**
     * 注册声纹特征（文件上传）
     * 
     * @param username 用户名
     * @param audioFile 音频文件
     * @return 注册结果
     */
    @PostMapping("/register-voiceprint")
    public ResponseEntity<ApiResponse<Map<String, Object>>> registerVoiceprint(
            @RequestParam("username") String username,
            @RequestParam("audioFile") MultipartFile audioFile) {
        try {
            log.info("收到注册声纹特征请求，用户名: {}, 文件: {}", 
                    username, audioFile.getOriginalFilename());
            
            // 参数验证
            if (username == null || username.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("用户名不能为空", "INVALID_USERNAME")
                );
            }
            
            if (audioFile == null || audioFile.isEmpty()) {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("音频文件不能为空", "INVALID_AUDIO_FILE")
                );
            }
            
            Map<String, Object> result = authService.registerVoiceprint(username.trim(), audioFile);
            
            return ResponseEntity.ok(ApiResponse.success("注册声纹特征成功", result));
        } catch (Exception e) {
            log.error("注册声纹特征失败", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "REGISTER_VOICEPRINT_FAILED")
            );
        }
    }

    /**
     * 注册声纹特征（Base64数据）
     * 
     * @param request 声纹注册请求
     * @return 注册结果
     */
    @PostMapping("/register-voiceprint-base64")
    public ResponseEntity<ApiResponse<Map<String, Object>>> registerVoiceprintBase64(
            @Valid @RequestBody VoiceprintLoginRequest request) {
        try {
            log.info("收到注册声纹特征请求（Base64），用户名: {}", request.getUsername());
            
            Map<String, Object> result = authService.registerVoiceprint(
                request.getUsername(), 
                request.getAudioBase64()
            );
            
            return ResponseEntity.ok(ApiResponse.success("注册声纹特征成功", result));
        } catch (Exception e) {
            log.error("注册声纹特征失败（Base64）", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "REGISTER_VOICEPRINT_FAILED")
            );
        }
    }

    /**
     * 获取声纹注册朗诵文字
     * 
     * @param username 用户名
     * @return 朗诵文字
     */
    @GetMapping("/voiceprint-register/prompt/{username}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getVoiceprintPrompt(
            @PathVariable("username") String username) {
        try {
            Map<String, Object> result = new HashMap<>();
            result.put("promptText", "请朗诵：我是" + username + "，正在进行声纹注册");
            result.put("username", username);
            
            return ResponseEntity.ok(ApiResponse.success("获取朗诵文字成功", result));
        } catch (Exception e) {
            log.error("获取朗诵文字失败", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "GET_PROMPT_FAILED")
            );
        }
    }

    /**
     * 声纹注册（兼容前端路径）- 支持表单数据
     * 用户需要朗诵固定文字："我是[用户名]，正在进行声纹注册"
     * 
     * @param username 用户名
     * @param audioFile 音频文件（可选）
     * @param audioBase64 音频Base64数据（可选）
     * @return 注册结果
     */
    @PostMapping("/voiceprint-register")
    public ResponseEntity<ApiResponse<Map<String, Object>>> voiceprintRegister(
            @RequestParam("username") String username,
            @RequestParam(value = "audioFile", required = false) MultipartFile audioFile,
            @RequestParam(value = "audioBase64", required = false) String audioBase64) {
        try {
            log.info("收到声纹注册请求，用户名: {}", username);
            
            // 参数验证
            if (username == null || username.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("用户名不能为空", "USERNAME_REQUIRED")
                );
            }
            
            Map<String, Object> result;
            
            // 优先处理文件上传，其次处理Base64数据
            if (audioFile != null && !audioFile.isEmpty()) {
                log.info("处理音频文件: {}", audioFile.getOriginalFilename());
                result = authService.registerVoiceprint(username.trim(), audioFile);
            } else if (audioBase64 != null && !audioBase64.trim().isEmpty()) {
                log.info("处理Base64音频数据");
                result = authService.registerVoiceprint(username.trim(), audioBase64.trim());
            } else {
                return ResponseEntity.badRequest().body(
                    ApiResponse.error("音频文件或音频数据不能为空", "AUDIO_REQUIRED")
                );
            }
            
            // 添加朗诵提示文字到返回结果中
            result.put("promptText", "请朗诵：我是" + username + "，正在进行声纹注册");
            
            return ResponseEntity.ok(ApiResponse.success("声纹注册成功", result));
        } catch (Exception e) {
            log.error("声纹注册失败", e);
            return ResponseEntity.badRequest().body(
                ApiResponse.error(e.getMessage(), "VOICEPRINT_REGISTER_FAILED")
            );
        }
    }

    /**
     * 启用声纹识别
     * 
     * @param userId 用户ID
     * @param request 请求体包含音频数据
     * @return 操作结果
     */
    @PostMapping("/enable-voiceprint/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> enableVoiceprint(
            @PathVariable("userId") Long userId,
            @RequestBody Map<String, String> request) {
        try {
            log.info("收到启用声纹识别请求，用户ID: {}", userId);
            
            String audioBase64 = request.get("audioBase64");
            if (audioBase64 == null || audioBase64.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(ApiResponse.error("音频数据不能为空", "AUDIO_REQUIRED"));
            }
            
            User user = userService.enableVoiceprint(userId, audioBase64);
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", user.getId());
            responseData.put("username", user.getUsername());
            responseData.put("voiceprintEnabled", user.getIsVoiceprintEnabled());
            responseData.put("voiceprintFeatureId", user.getVoiceprintFeatureId());
            
            return ResponseEntity.ok(ApiResponse.success("声纹识别启用成功", responseData));
        } catch (Exception e) {
            log.error("启用声纹识别失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "ENABLE_VOICEPRINT_FAILED"));
        }
    }

    /**
     * 禁用声纹识别
     * 
     * @param userId 用户ID
     * @return 操作结果
     */
    @PostMapping("/disable-voiceprint/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> disableVoiceprint(@PathVariable("userId") Long userId) {
        try {
            log.info("收到禁用声纹识别请求，用户ID: {}", userId);
            
            User user = userService.disableVoiceprint(userId);
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", user.getId());
            responseData.put("username", user.getUsername());
            responseData.put("voiceprintEnabled", user.getIsVoiceprintEnabled());
            
            return ResponseEntity.ok(ApiResponse.success("声纹识别禁用成功", responseData));
        } catch (Exception e) {
            log.error("禁用声纹识别失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "DISABLE_VOICEPRINT_FAILED"));
        }
    }

    /**
     * 获取用户信息
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    @GetMapping("/user/{userId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getUserInfo(@PathVariable("userId") Long userId) {
        try {
            log.info("收到获取用户信息请求，用户ID: {}", userId);
            
            User user = userService.findById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", user.getId());
            responseData.put("username", user.getUsername());
            responseData.put("email", user.getEmail());
            responseData.put("voiceprintEnabled", user.getIsVoiceprintEnabled());
            responseData.put("isActive", user.getIsActive());
            responseData.put("createdAt", user.getCreatedAt());
            responseData.put("updatedAt", user.getUpdatedAt());
            
            return ResponseEntity.ok(ApiResponse.success("获取用户信息成功", responseData));
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "GET_USER_INFO_FAILED"));
        }
    }

    /**
     * 检查用户名是否可用
     * 
     * @param username 用户名
     * @return 检查结果
     */
    @GetMapping("/check-username/{username}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> checkUsername(@PathVariable("username") String username) {
        try {
            boolean exists = userService.findByUsername(username) != null;
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("username", username);
            responseData.put("available", !exists);
            
            return ResponseEntity.ok(ApiResponse.success("检查完成", responseData));
        } catch (Exception e) {
            log.error("检查用户名失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "CHECK_USERNAME_FAILED"));
        }
    }

    /**
     * 检查邮箱是否可用
     * 
     * @param email 邮箱
     * @return 检查结果
     */
    @GetMapping("/check-email/{email}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> checkEmail(@PathVariable("email") String email) {
        try {
            boolean exists = userService.findByEmail(email) != null;
            
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("email", email);
            responseData.put("available", !exists);
            
            return ResponseEntity.ok(ApiResponse.success("检查完成", responseData));
        } catch (Exception e) {
            log.error("检查邮箱失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage(), "CHECK_EMAIL_FAILED"));
        }
    }

    /**
     * 生成JWT Token（简化版本）
     * 实际项目中应该使用JWT库生成真正的token
     */
    private String generateToken(User user) {
        // 这里是简化版本，实际应该使用JWT
        return "token_" + user.getId() + "_" + System.currentTimeMillis();
    }
}